<template>
  <div id="app">
    <!-- 全屏遮罩层 -->
    <div class="full-screen-mask" v-if="isLoading">
      <div class="loading-content">
        <div class="loading-spinner">
          <i class="el-icon-loading"></i>
        </div>
        <div class="loading-text">正在加载数据，请稍候...</div>
      </div>
    </div>
    
    <div class="page-head">
      <div class="operation-box">
        <span class="form-title">时间:</span>
        <el-date-picker
            v-model="times"
            type="daterange"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            style="width: 220px"
            :picker-options="{
              disabledDate(time, current) {
                if (!current) return false;
                const startDate = current[0];
                const endDate = current[1];
                return startDate && time.getTime() < startDate.getTime();
              }
            }"
            @change="validateDateRange"
        >
        </el-date-picker>
        <!-- <span class="form-title">行数:</span>
        <el-input
            v-model.number="rowNum"
            style="width:60px"
        />
        <span class="form-title">列数:</span>
        <el-input
            v-model.number="colNum"
            style="width:60px"
        /> -->
        <el-input
            v-model="searchValue"
            placeholder="编号"
            clearable
            prefix-icon="el-icon-search"
            style="width: 120px"
            @clear="clearSearch"
        />
        <el-button type="primary" @click="filterSearchValue">搜索
          <template v-if="findList.length">
            {{ `${currentFindIndex + 1}/${findList.length}` }}
          </template>
        </el-button>
        <el-date-picker
          v-model="selectedDate"
          type="date"
          placeholder="选择预约日期"
          value-format="yyyy-MM-dd"
          :picker-options="{
            disabledDate(time) {
              return time.getTime() < Date.now() - 8.64e7; // 禁用今天之前的日期
            }
          }"
          @change="handleDateChange">
        </el-date-picker>
        <el-button type="success" @click="showAddDialog" :disabled="!selectedDate">新增预约</el-button>

        <!-- 新增预约弹窗 -->
        <el-dialog title="新增预约" :visible.sync="addDialogVisible" width="500px">
          <el-form :model="addForm" label-width="100px">
            <el-form-item label="已选择日期">
               {{ selectedDate }}
            </el-form-item>
            <el-form-item label="开始时间">
              <el-time-picker
                v-model="addForm.startTime"
                format="HH:mm:ss"
                value-format="HH:mm:ss"
                :picker-options="{
                  selectableRange: ['09:00:00 - 12:00:00', '14:00:00 - 18:00:00']
                }"
                @change="validateTimeRange"
                placeholder="选择开始时间">
              </el-time-picker>
            </el-form-item>
            <el-form-item label="结束时间">
              <el-time-picker
                v-model="addForm.endTime"
                format="HH:mm:ss"
                value-format="HH:mm:ss"
                :picker-options="{
                  selectableRange: ['09:00:00 - 12:00:00', '14:00:00 - 18:00:00'],
                  minTime: addForm.startTime
                }"
                :disabled="!addForm.startTime"
                placeholder="选择结束时间">
              </el-time-picker>
            </el-form-item>
            <el-form-item label="选择房间">
              <el-select v-model="addForm.room" placeholder="请选择房间">
                <el-option
                  v-for="(name, index) in nameList"
                  :key="roomIdList[index]"
                  :label="name"
                  :value="roomIdList[index]">
                </el-option>
              </el-select>
            </el-form-item>
          </el-form>
          <span slot="footer" class="dialog-footer">
            <el-button @click="addDialogVisible = false">取 消</el-button>
            <el-button type="primary" @click="handleAddSubmit">确 定</el-button>
          </span>
        </el-dialog>
        
        <!-- 编辑预约弹窗 -->
        <el-dialog title="编辑预约" :visible.sync="editDialogVisible" width="500px">
          <el-form :model="editForm" label-width="100px">
            <el-form-item label="工单号">
               {{ editForm.orderNum }}
            </el-form-item>
            <el-form-item label="日期">
               {{ editForm.dateStr }}
            </el-form-item>
            <el-form-item label="开始时间">
              <el-time-picker
                v-model="editForm.startTime"
                format="HH:mm:ss"
                value-format="HH:mm:ss"
                :picker-options="{
                  selectableRange: ['09:00:00 - 12:00:00', '14:00:00 - 18:00:00']
                }"
                @change="validateEditTimeRange"
                placeholder="选择开始时间">
              </el-time-picker>
            </el-form-item>
            <el-form-item label="结束时间">
              <el-time-picker
                v-model="editForm.endTime"
                format="HH:mm:ss"
                value-format="HH:mm:ss"
                :picker-options="{
                  selectableRange: ['09:00:00 - 12:00:00', '14:00:00 - 18:00:00'],
                  minTime: editForm.startTime
                }"
                :disabled="!editForm.startTime"
                placeholder="选择结束时间">
              </el-time-picker>
            </el-form-item>
            <el-form-item label="选择房间">
              <el-select v-model="editForm.room" placeholder="请选择房间">
                <el-option
                  v-for="(name, index) in nameList"
                  :key="roomIdList[index]"
                  :label="name"
                  :value="roomIdList[index]">
                </el-option>
              </el-select>
            </el-form-item>
          </el-form>
          <span slot="footer" class="dialog-footer">
            <el-button @click="editDialogVisible = false">取 消</el-button>
            <el-button type="primary" @click="handleEditSubmit">确 定</el-button>
          </span>
        </el-dialog>
        <!-- <el-button type="primary" @click="classifyDialogVisible=true">数据分类</el-button> -->
      </div>
      <el-popover
          placement="right"
          width="400"
          trigger="click">
        <div class="gantt-config-options">
          <el-form :inline="true" size="small">
            <el-form-item label="行高">
              <el-slider
                  v-model="cellHeight"
                  :min="20"
                  :max="100"
                  style="width:80px"
                  size="small"
              ></el-slider>
            </el-form-item>
            <el-form-item label="单位刻度宽">
              <el-slider
                  v-model="cellWidth"
                  :min="20"
                  :max="100"
                  style="width:80px"
                  size="small"
              ></el-slider>
            </el-form-item>
            <el-form-item label="每刻度时长">
              <el-select
                  v-model="scale"
                  placeholder=""
                  style="width:100px"
                  size="small"
              >
                <el-option
                    v-for="item in scaleList"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                >
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-checkbox v-model="hideHeader">隐藏头部</el-checkbox>
            </el-form-item>
            <el-form-item>
              <el-checkbox :value="showMovedBlock" @change="setShowMovedBlock" title="是否显示拖拽之前的甘特块，若勾选，显示为黑色阴影状">
                显示调整前任务
              </el-checkbox>
            </el-form-item>
            <el-form-item>
              <el-checkbox :value="showDragConfirm" @change="setShowDragConfirm" title="调整任务时是否显示确认弹窗">显示调整确认弹窗
              </el-checkbox>
            </el-form-item>
          </el-form>

        </div>
        <el-button slot="reference" type="primary" style="margin-left: 10px;">配置项</el-button>
      </el-popover>

    </div>
    <div class="page-body">
      <v-gantt-chart
          :currentTime="currentTime"
          :startTime="times[0]"
          :endTime="times[1]"
          :cellWidth="cellWidth"
          :cellHeight="cellHeight"
          :timeLines="timeLines"
          :titleHeight="titleHeight"
          :scale="scale"
          :titleWidth="titleWidth"
          :showCurrentTime="true"
          :hideHeader="hideHeader"
          :dataKey="dataKey"
          :datas="datas"
          @click.native="clearTipMessage"
      >
      </v-gantt-chart>
      
      <!-- 底部提示区域 -->
      <div class="bottom-tip-area" v-if="tipMessage">
        <div class="tip-message">{{ tipMessage }}</div>
      </div>
    </div>
    <el-dialog
        title="数据分类"
        :visible.sync="classifyDialogVisible">
      <el-form class="classify-form">
        <el-form-item label="类型：">
          <el-checkbox-group v-model="selectRowTypes">
            <el-checkbox
                v-for="(rowType,index) in rowTypes"
                :key="index"
                :label="rowType">{{ rowType }}
            </el-checkbox>
          </el-checkbox-group>
        </el-form-item>
        <el-form-item label="速度：">
          <el-checkbox-group v-model="selectSpeedTypes">
            <el-checkbox
                v-for="(speed,index) in speedTypes"
                :key="index"
                :label="speed">{{ speed }}
            </el-checkbox>
          </el-checkbox-group>
        </el-form-item>
      </el-form>
      <div style="text-align: right;padding-top: 25px;">
        <el-button @click="classifyDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="classifyData">确定</el-button>
      </div>
    </el-dialog>
    <el-dialog
        title="任务调整"
        :visible.sync="checkDialogVisible"
        width="1000px">

      <check-adjust ref="checkAdjust" @closeDialog="checkDialogVisible=false"/>

    </el-dialog>
    
  </div>
</template>

<script>
import dayjs from "dayjs";
import {cloneDeep} from "lodash";
import {mapMutations, mapState} from "vuex";
import checkAdjust from "./components/demo/checkAdjust.vue";
import {
  getWidthAbout2Times as _getWidthAbout2Times
} from "@/utils/gtUtils.js";
import {checkConflict} from "@/utils/tool.js";
import {fetchSchedulingData, fetchHolidayData} from "@/api/mock-data";
import axios from 'axios';
import { getAuthToken } from './api/mock-data';

const scaleList = `5,10,15,20,30,60`
    .split(",")
    .map(n => {
      let value = parseInt(n);
      let label;
      if (value < 60) {
        label = value + "分钟";
      } else {
        label = value / 60 + "小时";
      }
      return {
        value,
        label
      };
    });
export default {
  name: "App",
  components: {checkAdjust},
  data() {
    return {
      isLoading: true, // 用于控制加载状态
      searchValue: "",
      timeLines: [], // 初始化为空数组，自定义时间线只在点击后显示
      currentTime: dayjs(),
      cellWidth: 100, // 增加默认宽度，让短时间会议显示更清晰
      cellHeight: 50,
      titleHeight: 60,
      titleWidth: 250,
      scale: 15, // 默认使用15分钟的刻度
      times: [
        dayjs()
            .set("hour", 0)
            .set("minute", 0)
            .toString(),
        dayjs()
            .add(1, "day") // 默认只显示一天的时间范围
            .set("hour", 23)
            .set("minute", 59)
            .toString()
      ],
      rowNum: 500,
      colNum: 25,
      datas: [], // 修改为空数组，而不是嵌套数组
      dataKey: "id",
      scaleList: scaleList,
      scrollToTime: dayjs()
          .add(1, "day")
          .toString(),
      hideHeader: false,
      positionB: {},
      positionA: {},
      ganttData: [],
      classifyDialogVisible: false,
      checkDialogVisible: false,
      rowTypes: ["🚅", "🚈", "🚄"],
      speedTypes: ["0~50", "50~100", "100"],
      selectRowTypes: [],
      selectSpeedTypes: [],
      classifyTypeList: [],
      rawData: [],
      findList: [],
      currentFindIndex: 0,
      tipMessage: "", // 添加提示信息
      addDialogVisible: false,
      selectedDate: '', // 选择的日期
      addForm: {
        startTime: '',
        endTime: '',
        room: ''
      },
      nameList: [],  // 添加房间名称列表
      roomIdList: [], // 添加房间ID列表
      editDialogVisible: false, // 新增编辑预约弹窗显示状态
      editForm: { // 新增编辑表单数据
        id: '',
        dateStr: '',
        startTime: '',
        endTime: '',
        room: '',
        orderNum: '' // 添加工单号字段
      }
    };
  },
  watch: {
    showRowList() {
      this.classifyData();
    },
    cellWidth(){
      setTimeout(()=>{
        this.$bus.$emit("refresh");
      },500)
    },
    scale(){
      setTimeout(()=>{
        this.$bus.$emit("refresh");
      },500)
    },
    times: {
      deep: true,
      handler(newVal, oldVal) {
        // 时间范围变化时，刷新图表
        if (newVal && oldVal && 
            (newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
          setTimeout(() => {
            this.$bus.$emit("refresh");
          }, 300);
        }
      }
    }
  },
  computed: {
    ...mapState([
      "filterBlockId",
      "currentBlock",
      "currentRow",
      "targetBlock",
      "targetRow",
      "showRowList",
      "rawRowList",
      "showMovedBlock",
      "showDragConfirm"
    ])
  },
  mounted() {
    // 显示加载状态，启用遮罩层
    this.isLoading = true;
    
    // 记录开始加载时间
    const startTime = new Date().getTime();
    console.log('开始加载时间:', startTime);
    
    // 确保currentTime是最新的
    this.currentTime = dayjs();
    
    // 页面加载时获取预约信息
    this.fetchSchedulingPlanByOrderNo();
    
    // 固定等待4秒后移除遮罩层，确保所有数据都加载完成
    setTimeout(() => {
      console.log('固定等待4秒结束，移除遮罩层');
      this.isLoading = false;
    }, 4000);
    
    this.$bus.$on("updateTimeLines", (timeParam) => {
      this.updateTimeLines(timeParam.start, timeParam.end);
    });

    this.$bus.$on("toggleGroupOpen", (index) => {
      this.toggleGroupOpen(index);
    });

    this.$bus.$on("updateCurrentTime", (time) => {
      this.currentTime = time
    });
    
    this.$bus.$on("dragTask", () => {
      this.dragTask();
    });
    
    // 监听数据生成事件
    this.$bus.$on("dataGenerated", (generatedData) => {
      if (Array.isArray(generatedData) && generatedData.length > 0) {
        this.setRawRowList(generatedData);
        this.setShowRowList(cloneDeep(generatedData));
        this.classifyData();
        // 数据加载完成，关闭加载状态
        this.isLoading = false;
      }
    });
    
    // 将$bus暴露给全局，以便其他模块可以使用
    window.$bus = this.$bus;
    
    // 移除旧的详情弹窗事件监听
    this.$bus.$off('openDetailDialog');
    
    // 监听显示提示信息事件
    this.$bus.$on('showTipMessage', (message) => {
      this.showTipMessage(message);
    });
    
    // 监听清除提示信息事件
    this.$bus.$on('clearTipMessage', () => {
      this.clearTipMessage();
    });
    
    // 获取当前年份的节假日数据
    const currentYear = 2025;
    fetchHolidayData(currentYear);

    // 监听房间列表更新事件
    window.addEventListener('roomListUpdated', (event) => {
      if (event.detail) {
        this.nameList = event.detail;
        // 从mock-data.js中获取房间ID列表
        import('./api/mock-data').then(module => {
          this.roomIdList = module.getRoomIdList();
        });
      }
    });
    
    // 监听编辑任务事件
    this.$bus.$on('edit-task', (params) => {
      this.handleEditTask(params);
    });
    
    // 监听删除任务事件
    this.$bus.$on('delete-task', (params) => {
      this.handleDeleteTask(params);
    });
  },
  beforeDestroy() {
    // 移除事件监听器
    this.$bus.$off('openDetailDialog');
    this.$bus.$off('showTipMessage');
    this.$bus.$off('clearTipMessage');
    this.$bus.$off('edit-task');
    this.$bus.$off('delete-task');
    window.removeEventListener('roomListUpdated', this.handleRoomListUpdated);
  },
  methods: {
    ...mapMutations([
      "setFilterBlockId",
      "setCurrentBlock",
      "setCurrentRow",
      "setCutBlock",
      "setCutRow",
      "setShowRowList",
      "setRawRowList",
      "setShowMovedBlock",
      "setShowDragConfirm"
    ]),
    getWidthAbout2Times(start, end) {
      const options = {
        scale: this.scale,
        cellWidth: this.cellWidth
      };
      return _getWidthAbout2Times(start, end, options);
    },
    // 用于手动点击按钮生成数据
    generateData() {
      // 显示加载状态
      this.isLoading = true;
      
      try {
        // 使用setTimeout模拟数据生成过程
        setTimeout(async () => {
          try {
            let list = await fetchSchedulingData();
            
            if (list && list.length > 0) {
              this.setRawRowList(list);
              this.setShowRowList(cloneDeep(list));
              this.classifyData();
            }
            
            // 数据生成完成，关闭加载状态
            this.isLoading = false;
          } catch (error) {
            this.isLoading = false;
          }
        }, 300);
      } catch (error) {
        this.isLoading = false;
      }
    },
    
    // 用于初始化或接收到接口数据时生成数据
    async initData() {
      try {
        let list = await fetchSchedulingData();
        if (list && list.length > 0) {
          this.setRawRowList(list);
          this.setShowRowList(cloneDeep(list));
          this.classifyData();
        } else {
          this.setRawRowList([]);
          this.setShowRowList([]);
          this.datas = [];
        }
      } catch (error) {
        this.setRawRowList([]);
        this.setShowRowList([]);
        this.datas = [];
      }
    },
    updateTimeLines(timeA, timeB) {
      // 更新时间线，添加自定义时间线
      this.timeLines = [
        {
          time: timeA,
          text: "开始时间",
          color: "#1890ff" // 使用蓝色标识开始时间线
        },
        {
          time: timeB,
          text: "结束时间",
          color: "#f5222d" // 使用红色标识结束时间线
        }
      ];
      
      // 显示提示信息
      this.showTipMessage("已设置自定义时间范围");
    },
    /* 数据分组*/
    classifyData() {

      function combine(arr) {
        let result = [];
        (function f(t, a, n) {
          if (n === 0) return result.push(t);
          for (let i = 0; i < a[n - 1].length; i++) {
            f(t.concat(a[n - 1][i]), a, n - 1);
          }
        })([], arr, arr.length);
        return result;
      }

      let typeList = this.selectRowTypes.length ? this.selectRowTypes : [""];
      let speedList = this.selectSpeedTypes.length ? this.selectSpeedTypes : [""];
      /*
      混和类型和速度属性
      例：选中两个类型和两个速度，["🚅", "🚈"]和["0~50", "50~100"]  最终会生成四种混合类型的数组，如果都选中三个，最终结果则是9个
     [
        [
          "0~50",
          "🚅"
        ],
        [
          "0~50",
          "🚈"
        ],
        [
          "50~100",
          "🚅"
        ],
        [
          "50~100",
          "🚈"
        ]
    ]

      */

      let resultArr = combine([typeList, speedList]);
      let classifyList = [];
      resultArr.forEach(resultItem => {
        //新建空对象，依次赋值, 建立最终类型数组
        let tempObj = {};
        if (resultItem[0]) {
          tempObj["speed"] = resultItem[0];
        }
        if (resultItem[1]) {
          tempObj["type"] = resultItem[1];
        }
        if (Object.getOwnPropertyNames(tempObj).length) {
          classifyList.push(tempObj);
        }
        /*将数组转为对象，最终是4个这样的对象
          [
            {
              "speed": "0~50",
              "type": "🚅"
            },
            {
              "speed": "0~50",
              "type": "🚈"
            },
            {
              "speed": "50~100",
              "type": "🚅"
            },
            {
              "speed": "50~100",
              "type": "🚈"
            }
          ]
          */
      });
      this.classifyTypeList = classifyList;
      if (!classifyList.length) {
        // 确保datas始终是一个数组
        this.datas = [
          {
            groupType: {},
            children: cloneDeep(this.showRowList),
            isOpen: true
          }
        ];
        return false;
      }
      let groupList = [];

      /* 遍历每一个类型对象，并筛选对应的行，添加到每一个甘特组的children里*/
      classifyList.forEach(classifyItem => {
        let tempObj = Object.assign({}, classifyItem);
        tempObj["children"] = [];
        let blockRowList = cloneDeep(this.showRowList);
        for (let filterKey in classifyItem) {
          blockRowList = blockRowList.filter(bridgeItem => {
            if (filterKey === "speed") {
              let speedLimit = classifyItem[filterKey].split("~");
              if (speedLimit.length === 2) {
                return bridgeItem.speed >= speedLimit[0] && bridgeItem.speed < speedLimit[1];
              } else {
                return bridgeItem.speed >= speedLimit[0];
              }
            }
            return bridgeItem[filterKey] == classifyItem[filterKey];
          });
        }
        blockRowList.forEach((item, index) => {
          // 遍历每一行生成一个rawIndex属性，这个属性用来计算每一行的top值
          item.rawIndex = index;
        });
        tempObj["children"] = blockRowList;
        tempObj["groupType"] = classifyItem;
        tempObj["isOpen"] = true;
        groupList.push(tempObj);
      });
      // 确保datas始终是一个数组
      this.datas = Array.isArray(groupList) ? groupList : []; 
      this.classifyDialogVisible = false;
    },
    /* 查找*/
    filterSearchValue() {
      if (!this.searchValue) {
        this.$message.warning('编号不能为空~');
        return false;
      }
      
      // 清除自定义时间线
      this.timeLines = [];
      
      // 使用输入的编号调用接口
      this.fetchSchedulingPlanByInputOrderNum(this.searchValue);
    },
    
    // 根据输入的编号获取预约信息并跳转
    async fetchSchedulingPlanByInputOrderNum(orderNum) {
      try {
        const token = getAuthToken();
        
        if (!token) {
          this.$message.warning('未找到认证信息');
          return;
        }
        
        console.log('正在搜索预约信息，工单号:', orderNum);
        
        // 显示加载状态
        this.isLoading = true;
        
        // 清除自定义时间线
        this.timeLines = [];
        
        // 调用接口获取预约信息
        const response = await axios.get('http://10.77.162.117:18092/admin/tjsScheduling/schedulingPlan/list', {
          params: { 
            order_num: orderNum.trim()
          },
          headers: {
            'Authorization': `Bearer ${token}`
          }
        }).catch(error => {
          console.error('请求出错:', error.response || error);
          
          // 尝试使用不同的参数名
          if (error.response && error.response.status === 500) {
                          return axios.get('http://10.77.162.117:18092/admin/tjsScheduling/schedulingPlan/list', {
                params: { 
                  orderNum: orderNum.trim() // 尝试使用驼峰命名
                },
                headers: {
                  'Authorization': `Bearer ${token}`
                }
              });
          }
          throw error;
        });
        
        console.log('接口返回数据:', response.data);
        
        if (response.data.code === 200 && response.data.data && response.data.data.data && response.data.data.data.length > 0) {
          const schedulingPlan = response.data.data.data[0];
          
          // 提取日期和时间
          const startTime = dayjs(schedulingPlan.start_time);
          const dateStr = startTime.format('YYYY-MM-DD');
          
          console.log('找到预约信息:', schedulingPlan);
          console.log('预约日期时间:', dateStr, startTime.format('HH:mm:ss'));
          
          // 设置选中日期
          this.selectedDate = dateStr;
          
          // 更新甘特图的时间范围
          this.times = [
            startTime.startOf('day').toString(),
            startTime.endOf('day').toString()
          ];
          
          // 等待视图更新后滚动到指定时间
          this.$nextTick(() => {
            // 计算从当天开始到预约开始时间的宽度
            const scrollPosition = this.getWidthAbout2Times(
              startTime.startOf('day'),
              startTime
            );
            
            // 滚动到预约开始时间
            this.$bus.$emit("scrollToPosition", {
              x: -scrollPosition,
              y: 0
            });
            
            // 显示提示信息
            this.showTipMessage(`已找到工单号 ${schedulingPlan.order_num} 的预约，时间: ${startTime.format('YYYY-MM-DD HH:mm')}`);
          });
          
          // 清空搜索相关变量
          this.findList = [];
          this.currentFindIndex = 0;
          
        } else {
          this.$message.warning('未找到对应编号的预约信息');
          console.log('未找到预约信息或数据格式不正确');
        }
      } catch (error) {
        console.error('搜索预约信息失败:', error);
        this.$message.error('搜索预约信息失败，请检查网络连接或联系管理员');
      } finally {
        // 确保加载状态被关闭
        this.isLoading = false;
      }
    },
    
    clearSearch() {
      this.setFilterBlockId('');
      this.currentFindIndex = 0;
      this.findList = [];
      this.searchValue = '';
    },
    dragTask() {
      if (this.showDragConfirm) {
        this.checkAssign();
      } else {
        this.dragBlock();
      }
    },
    checkAssign() {
      this.checkDialogVisible = true;
      this.$nextTick(() => {
        this.$refs.checkAdjust.calcConflictList();
      });
    },
    dragBlock() {
      let adjustList = [];
      if (this.targetRow && this.currentBlock) {
        let adjustOjb = checkConflict(this.currentBlock, this.targetRow, this.targetBlock ? this.targetBlock : null);
        adjustList.push(adjustOjb);
      }
      if (this.currentRow && this.targetBlock) {
        let adjustOjb = checkConflict(this.targetBlock, this.currentRow, this.currentBlock ? this.currentBlock : null);
        adjustList.push(adjustOjb);
      }

      // 判断是否有冲突
      let hasConflict = adjustList.some(adjustObj => {
        return adjustObj.conflictList.length > 0;
      });
      if (hasConflict) {
        this.$message.error("调整任务存在时间冲突，请检查！");
      }
      let rowList = cloneDeep(this.showRowList);
      adjustList.forEach(adjustItem => {
        let currentRow = rowList.find(row => row.id === adjustItem.blockItem.parentId);

        if (this.showMovedBlock) {
          let movedBeforeBlock = currentRow.gtArray.find(blockItem => {
            return blockItem.id === adjustItem.blockId;
          });
          if (movedBeforeBlock["movedStatus"] === "after") {
            // 已经移动过一次的情况，过滤掉
            currentRow.gtArray = currentRow.gtArray.filter(blockItem => blockItem.id !== adjustItem.blockId);
          } else {
            // 没有移动过，修改movedStatus为before
            movedBeforeBlock["movedStatus"] = "before";
          }
        } else {
          currentRow.gtArray = currentRow.gtArray.filter(blockItem => blockItem.id !== adjustItem.blockId);
        }
        let newBlock = cloneDeep(adjustItem.blockItem);
        let targetRow = rowList.find(row => row.id === adjustItem.targetRowId);
        newBlock["movedStatus"] = "after";
        newBlock["parentId"] = targetRow.id;
        targetRow.gtArray.push(newBlock);
      });
      this.setCutBlock(null);
      this.setCutRow(null);
      this.setShowRowList(rowList);
    },
    toggleGroupOpen(index) {
      this.datas[index].isOpen = !this.datas[index].isOpen;
    },
    
    // 格式化日期时间
    formatDateTime(dateTime) {
      return dayjs(dateTime).format('YYYY-MM-DD HH:mm');
    },
    
    // 获取任务状态
    getTaskStatus(task) {
      let start = dayjs(task.start);
      let end = dayjs(task.end);
      let now = this.currentTime;
      
      if (start.isBefore(now) && end.isAfter(now)) {
        return "进行中";
      } else if (end.isBefore(now)) {
        return "已完成";
      } else {
        return "未开始";
      }
    },
    
    // 显示提示信息
    showTipMessage(message) {
      this.tipMessage = message;
    },
    
    // 清除提示信息
    clearTipMessage() {
      this.tipMessage = "";
    },
    
    // 格式化时间显示
    formatTime(time) {
      return dayjs(time).format("YYYY-MM-DD HH:mm");
    },
    
    // 获取会议状态
    getMeetingStatus(task) {
      const now = dayjs();
      const start = dayjs(task.start);
      const end = dayjs(task.end);
      
      if (start.isAfter(now)) {
        return "未开始";
      } else if (end.isBefore(now)) {
        return "已结束";
      } else {
        return "进行中";
      }
    },
    
    // 处理编辑任务
    async handleEditTask(params) {
      // 打开编辑弹窗
      this.showEditDialog(params);
    },
    
    // 处理删除任务
    async handleDeleteTask(params) {
      // 显示确认对话框
      this.$confirm('确认删除该任务?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        try {
          this.isLoading = true;
          
          const token = getAuthToken();
          if (!token) {
            this.$message.warning('未找到认证信息');
            return;
          }
          
          const response = await axios.post(
            'http://10.77.162.117:18092/admin/tjsScheduling/schedulingPlan/delete',
            { id: params.id },
            {
              headers: {
                'Authorization': `Bearer ${token}`
              }
            }
          );
          
          if (response.data.code === 0 || response.data.code === 200) {
            this.$message.success('删除成功');
            // 刷新数据
            this.initData();
          } else {
            this.$message.error(response.data.msg || '删除失败');
          }
        } catch (error) {
          console.error('删除任务失败:', error);
          this.$message.error('删除任务失败：' + (error.response?.data?.msg || error.message));
        } finally {
          this.isLoading = false;
        }
      }).catch(() => {
        // 用户取消删除，不做任何操作
      });
    },
    
    showAddDialog() {
      if (!this.selectedDate) {
        this.$message.warning('请先选择预约日期');
        return;
      }
      this.addDialogVisible = true;
    },
    handleDateChange(date) {
      if (date) {
        // 清除自定义时间线
        this.timeLines = [];
        
        // 更新甘特图的时间范围到选择的日期
        const selectedDate = dayjs(date);
        
        // 更新时间线配置，保持一天的范围，但从上午9点开始显示
        this.times = [
          selectedDate.startOf('day').toString(),
          selectedDate.endOf('day').toString()
        ];
        
        // 设置滚动位置到上午9点
        this.$nextTick(() => {
          const nineAM = selectedDate.hour(9).minute(0).second(0);
          const scrollPosition = this.getWidthAbout2Times(selectedDate.startOf('day'), nineAM);
          this.$bus.$emit("scrollToPosition", {
            x: -scrollPosition,
            y: 0
          });
        });
        
        // 重置表单
        this.addForm = {
          startTime: '',
          endTime: '',
          room: ''
        };
      }
    },
    async handleAddSubmit() {
      if (!this.addForm.startTime || !this.addForm.endTime || !this.addForm.room) {
        this.$message.error('请填写完整信息');
        return;
      }

      try {
        const orderId = localStorage.getItem('orderId');
        if (!orderId) {
          this.$message.error('未找到工单信息');
          return;
        }

        const startTime = `${this.selectedDate} ${this.addForm.startTime}`;
        const endTime = `${this.selectedDate} ${this.addForm.endTime}`;

        const response = await axios.post(
          'http://10.77.162.117:18092/admin/tjsScheduling/schedulingPlan/create',
          {
            start_time: startTime,
            end_time: endTime,
            mediationOrder: orderId,
            room: this.addForm.room
          },
          {
            headers: {
              'Authorization': `Bearer ${getAuthToken()}`
            }
          }
        );

        if (response.data.code === 200) {
          this.$message.success('预约添加成功');
          this.addDialogVisible = false;
          // 刷新数据
          this.initData();
        } else {
          this.$message.error(response.data.msg || '添加失败');
        }
      } catch (error) {
        this.$message.error('添加失败：' + (error.response?.data?.msg || error.message));
      }
    },
    validateTimeRange(time) {
      // 如果已经选择了结束时间，但开始时间大于或等于结束时间，则清空结束时间
      if (this.addForm.endTime && this.addForm.startTime >= this.addForm.endTime) {
        this.addForm.endTime = '';
      }
      
      // 检查是否跨时段选择
      if (this.addForm.startTime && this.addForm.endTime) {
        const startHour = parseInt(this.addForm.startTime.split(':')[0]);
        const endHour = parseInt(this.addForm.endTime.split(':')[0]);
        
        // 如果开始时间在上午，结束时间在下午，则清空结束时间
        if ((startHour >= 9 && startHour < 12) && (endHour >= 14 && endHour <= 18)) {
          this.$message.warning('不能跨越午休时间预约');
          this.addForm.endTime = '';
        }
      }
    },
    
    // 获取指定工单号的预约信息
    async fetchSchedulingPlanByOrderNo() {
      try {
        const orderNo = localStorage.getItem('orderNo');
        const token = getAuthToken();
        
        if (!orderNo || !token) {
          console.log('未找到工单号或认证信息');
          this.initData(); // 仍然初始化数据
          return;
        }
        
        console.log('正在获取预约信息，工单号:', orderNo);
        
        // 清除自定义时间线
        this.timeLines = [];
        
        // 检查参数格式
        const response = await axios.get('http://10.77.162.117:18092/admin/tjsScheduling/schedulingPlan/list', {
          params: { 
            order_num: orderNo.trim() // 确保没有多余的空格
          },
          headers: {
            'Authorization': `Bearer ${token}`
          }
        }).catch(error => {
          console.error('请求出错:', error.response || error);
          
          // 尝试使用不同的参数名
          if (error.response && error.response.status === 500) {
            return axios.get('http://10.77.162.117:18092/admin/tjsScheduling/schedulingPlan/list', {
              params: { 
                orderNum: orderNo.trim() // 尝试使用驼峰命名
              },
              headers: {
                'Authorization': `Bearer ${token}`              }
            });
          }
          throw error;
        });
        
        console.log('接口返回数据:', response.data);
        
        if (response.data.code === 200 && response.data.data && response.data.data.data && response.data.data.data.length > 0) {
          const schedulingPlan = response.data.data.data[0];
          
          // 提取日期和时间
          const startTime = dayjs(schedulingPlan.start_time);
          const dateStr = startTime.format('YYYY-MM-DD');
          
          console.log('找到预约信息:', schedulingPlan);
          console.log('预约日期时间:', dateStr, startTime.format('HH:mm:ss'));
          
          // 设置选中日期
          this.selectedDate = dateStr;
          
          // 更新甘特图的时间范围
          this.times = [
            startTime.startOf('day').toString(),
            startTime.endOf('day').toString()
          ];
          
          // 等待视图更新后滚动到指定时间
          this.$nextTick(() => {
            // 计算从当天开始到预约开始时间的宽度
            const scrollPosition = this.getWidthAbout2Times(
              startTime.startOf('day'),
              startTime
            );
            
            // 滚动到预约开始时间
            this.$bus.$emit("scrollToPosition", {
              x: -scrollPosition,
              y: 0
            });
            
            // 显示提示信息
            this.showTipMessage(`已找到工单号 ${schedulingPlan.order_num} 的预约，时间: ${startTime.format('YYYY-MM-DD HH:mm')}`);
          });
        } else {
          console.log('未找到预约信息或数据格式不正确');
        }
        
        // 初始化甘特图数据
        this.initData();
      } catch (error) {
        console.error('获取预约信息失败:', error);
        
        // 显示错误提示
        this.$message.error('获取预约信息失败，请检查网络连接或联系管理员');
        
        // 初始化甘特图数据
        this.initData();
      }
      // 注意：不在这里设置isLoading状态，由定时器统一控制
    },
    showEditDialog(task) {
      // 确保房间列表已加载
      if (!this.nameList || this.nameList.length === 0) {
        // 从mock-data.js中获取房间列表
        import('./api/mock-data').then(module => {
          const token = module.getAuthToken();
          if (token) {
            // 触发房间列表加载
            window.dispatchEvent(new MessageEvent('message', {
              data: {
                type: 'setToken',
                token: token,
                id: localStorage.getItem('orderId'),
                orderNo: localStorage.getItem('orderNo')
              }
            }));
            
            // 设置一个监听器，等待房间列表加载完成后再打开弹窗
            const roomListListener = (event) => {
              if (event.detail && event.detail.length > 0) {
                this.nameList = event.detail;
                this.roomIdList = module.getRoomIdList();
                this._openEditDialog(task);
                window.removeEventListener('roomListUpdated', roomListListener);
              }
            };
            
            window.addEventListener('roomListUpdated', roomListListener);
          } else {
            this.$message.warning('未找到认证信息，无法加载房间列表');
          }
        });
      } else {
        // 房间列表已加载，直接打开弹窗
        this._openEditDialog(task);
      }
    },
    
    // 实际打开编辑弹窗的方法
    _openEditDialog(task) {
      console.log('编辑任务数据:', task);
      this.editForm = {
        id: task.recordId || task.id, // 优先使用recordId作为编辑表单的ID
        dateStr: dayjs(task.start).format('YYYY-MM-DD'),
        startTime: dayjs(task.start).format('HH:mm:ss'),
        endTime: dayjs(task.end).format('HH:mm:ss'),
        room: task.room || '',
        orderNum: task.id // 任务的id字段实际上是工单号
      };
      this.editDialogVisible = true;
    },
    async handleEditSubmit() {
      if (!this.editForm.startTime || !this.editForm.endTime || !this.editForm.room) {
        this.$message.error('请填写完整信息');
        return;
      }
 
      try {
        const token = getAuthToken();
        if (!token) {
          this.$message.warning('未找到认证信息');
          return;
        }
 
        const startTime = `${this.editForm.dateStr} ${this.editForm.startTime}`;
        const endTime = `${this.editForm.dateStr} ${this.editForm.endTime}`;
 
         // 获取mediationOrder，直接使用localStorage中的orderId
         const mediationOrder = localStorage.getItem('orderId');
         
         if (!mediationOrder) {
           this.$message.warning('未找到工单信息');
           return;
         }
 
         const response = await axios.post(
           'http://10.77.162.117:18092/admin/tjsScheduling/schedulingPlan/update',
           {
             id: this.editForm.id,
             start_time: startTime,
             end_time: endTime,
             mediationOrder: mediationOrder,
             room: this.editForm.room
           },
           {
             headers: {
               'Authorization': `Bearer ${token}`
             }
           }
         );
 
        if (response.data.code === 200) {
          this.$message.success('预约编辑成功');
          this.editDialogVisible = false;
          // 刷新数据
          this.initData();
        } else {
          this.$message.error(response.data.msg || '编辑失败');
        }
      } catch (error) {
        this.$message.error('编辑失败：' + (error.response?.data?.msg || error.message));
      }
    },
    validateEditTimeRange(time) {
      // 如果已经选择了结束时间，但开始时间大于或等于结束时间，则清空结束时间
      if (this.editForm.endTime && this.editForm.startTime >= this.editForm.endTime) {
        this.editForm.endTime = '';
      }
      
      // 检查是否跨时段选择
      if (this.editForm.startTime && this.editForm.endTime) {
        const startHour = parseInt(this.editForm.startTime.split(':')[0]);
        const endHour = parseInt(this.editForm.endTime.split(':')[0]);
        
        // 如果开始时间在上午，结束时间在下午，则清空结束时间
        if ((startHour >= 9 && startHour < 12) && (endHour >= 14 && endHour <= 18)) {
          this.$message.warning('不能跨越午休时间预约');
          this.editForm.endTime = '';
        }
      }
    },
    
    // 验证日期范围，确保结束日期不早于开始日期，并重新生成图表
    validateDateRange(dates) {
      if (dates && dates.length === 2) {
        const [startDate, endDate] = dates;
        if (dayjs(endDate).isBefore(dayjs(startDate))) {
          this.$message.warning('结束日期不能早于开始日期');
          this.times = [startDate, startDate]; // 如果选择了倒置的日期，则将结束日期设置为与开始日期相同
        }
        
        // 显示加载状态
        this.isLoading = true;
        
        // 清除自定义时间线，只保留当前时间线
        this.timeLines = [];
        
        // 重新初始化数据
        this.initData();
        
        // 确保至少显示2秒的加载状态
        setTimeout(() => {
          this.isLoading = false;
        }, 2000);
        
        // 刷新甘特图
        this.$nextTick(() => {
          this.$bus.$emit("refresh");
          
          // 滚动到合适的位置
          const scrollPosition = this.getWidthAbout2Times(
            dayjs(startDate).startOf('day'),
            dayjs(startDate).hour(9).minute(0).second(0) // 滚动到上午9点
          );
          
          this.$bus.$emit("scrollToPosition", {
            x: -scrollPosition,
            y: 0
          });
        });
      }
    }
    }
  }
;
</script>

<style lang="scss">
/* 底部提示区域样式 */
.bottom-tip-area {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
  background-color: rgba(0, 0, 0, 0.7);
  color: #fff;
  padding: 10px 0;
  text-align: center;
  z-index: 1000;
}

.tip-message {
  font-size: 14px;
}

/* 全屏遮罩层样式 */
.full-screen-mask {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(255, 255, 255, 0.95);
  z-index: 9999;
  display: flex;
  justify-content: center;
  align-items: center;
  pointer-events: all; /* 确保遮罩层可以捕获所有点击事件 */
}

.loading-content {
  text-align: center;
  padding: 30px;
  border-radius: 8px;
  background-color: white;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.loading-spinner {
  font-size: 40px;
  color: #409EFF;
  margin-bottom: 20px;
}

.loading-text {
  font-size: 16px;
  color: #606266;
}
</style>

